package com.jsc.common;


import cn.com.xib.sm.utils.SM2Util;
import com.alibaba.fastjson.*;
import com.jsc.common.utils.httputils.SSLClient;
import com.jsc.response.MessYeWu;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.*;
import org.apache.http.entity.*;
import org.apache.http.entity.mime.*;
import org.apache.http.entity.mime.content.*;
import org.apache.http.impl.client.*;
import org.apache.http.util.EntityUtils;


import java.io.*;
import java.nio.charset.*;
import java.util.*;

/**
 * @ClassName XiamenUtils
 * @Date 2021/7/2 0002 上午 9:02
 * @Author Administrator
 * @Description TODO
 * Version 1.0
 */
public class XiamenUtils {
    private static String privateKey = "58a56fe06e81724a88fc3e2282428e2773af14b9d720032cfa5ebfdadcd9d23e";
    private static String publicKey = "04c7457f9972b25722d1b7144fd27bd470befafaeb1c812db71fc4fc653f5e4d87a76d1069b2661b9feddfbc967a29cb23c223de2d5564159b9d7e33abd4b77eac";
    private static String thirdPartyPrivateKey = "041838FF0965F17C9D8C69AA1640523C2AD83ED5AD482A1F59774E75980A6190";
    private static String thirdPartyPublicKey = "0435B0F3DD1BEEE5497EFD806968B8EB78D95EF56B29984CAAFEFC75B4C1014807FF39E94AD86E1202C5779BFFDA57CA5EEAE61689524ECDEC697A7EC7EDDD6E6D";

    public static MessYeWu verifyAndDecrypt(String msg, boolean msgFromXib) {
        MessYeWu messYeWu = new MessYeWu<>();

        JSONObject jsonObject = JSON.parseObject(msg);
        String data = jsonObject.getString("data");
        String encrypt = jsonObject.getString("encrypt");
        // 随机数
        String nonceStr = jsonObject.getString("nonceStr");
        // 时间戳
        String timeStamp = jsonObject.getString("timeStamp");
        String signature = jsonObject.getString("sign");
        // 校验报文的时效性
        if (checkHasTimeout(timeStamp, System.currentTimeMillis())) {
            System.err.println("==========该返回报文已超时，请重新提交===生产直接阻断====");
            messYeWu.setMessage("报文超时，请重新提交");
            messYeWu.setStatus(false);
            return messYeWu;
        }
        //验证签名
        boolean verify = SM2Util.verifySignature(msgFromXib ? publicKey : thirdPartyPublicKey, data + encrypt + nonceStr + timeStamp, signature);
        if (!verify) {
            messYeWu.setMessage("报文签名不正确");
            messYeWu.setStatus(false);
            return messYeWu;
        }
        System.out.println("报文签名: " + verify);
        // 验证签名为true的时候，再进行解密数据
        if ("1".equals(encrypt)) {
            // 使用私钥钥进行解密
            data = SM2Util.decryptBySM2(data, msgFromXib ? thirdPartyPrivateKey : privateKey);
        }
        messYeWu.setMessage(data);
        messYeWu.setStatus(true);
        return messYeWu;
    }

    private static boolean checkHasTimeout(String timeStamp, long reqTime) {
        try {
            int diffTime = (int) ((reqTime - Long.parseLong(timeStamp)) / 1000L);
            /** 报文有效期需在10分钟内，否则视为失效，可防止过期报文重复发送 **/
            return Math.abs(diffTime) > 600;
        } catch (NumberFormatException e) {
            System.out.println("错误：" + e.getMessage());
            return true;
        }
    }

    /**
     * 生成参数
     *
     * @param plainText
     * @param isXibSend
     */
    public static String getSendPacket(String plainText, boolean isXibSend) {
        // 是否加密 1-加密 0-不加密
        String encrypt = "1";
        if ("1".equals(encrypt)) {
            // 使用接收方的公钥进行加密
            plainText = SM2Util.encryptBySM2(plainText, isXibSend ? thirdPartyPublicKey : publicKey);
        }
        // 随机数
        String nonceStr = getRandom();
        // 时间戳
        String timeStamp = "" + System.currentTimeMillis();

        // 使用发起方的私钥对base64的内容进行签名
        String signature = SM2Util.signature(isXibSend ? privateKey : thirdPartyPrivateKey, plainText + encrypt + nonceStr + timeStamp);
        // 生成最终的报文
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("timeStamp", timeStamp); // 时间戳
        data.put("nonceStr", nonceStr); // 随机数
        data.put("data", plainText);  //  报文字段
        data.put("encrypt", encrypt);  //  报文是否加密
        data.put("sign", signature);  // 签名数据
        return JSON.toJSONString(data);
    }

    private static String getRandom() {
        String sources = "0123456789abcdefghijklmnopqrstuvwxyz";
        Random rand = new Random();
        StringBuffer flag = new StringBuffer();

        for (int j = 0; j < 8; ++j) {
            flag.append(sources.charAt(rand.nextInt(35)) + "");
        }

        return String.valueOf(flag);
    }


    public static String postFormData(String jsonString, String filePath, String uri) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httppost = new HttpPost(uri);
            httppost.setHeader("Content-Type","charset=UTF-8");
            File file = new File(filePath);
            FileBody bin = new FileBody(file);
            StringBody comment = new StringBody(jsonString, ContentType.TEXT_PLAIN);
            HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addPart("guarantee_ofd", bin)
                    .addPart("data", comment)
                    .build();
            httppost.setEntity(reqEntity);
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    System.out.println("Response content length: " + resEntity.getContentLength());
                }
                EntityUtils.consume(resEntity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }

        return "0";
    }



    public static Map sendMultiFormMixData(String url, String filePaths, String data) throws Exception {
        HttpClient client = new SSLClient();
//        HttpClient client = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);
            // 设置传输参数,设置编码。设置浏览器兼容模式，解决文件名乱码问题
            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
//                    // 无法解决中文文件名？的问题
//                    ContentType contentType = ContentType.create("multipart/form-data", Charset.forName("UTF-8"));
//                    ContentBody fileBody = new FileBody(file, contentType);
                    ContentBody fileBody = new FileBody(new File(filePaths), ContentType.MULTIPART_FORM_DATA);
                    builder.addPart("guarantee_pdf", fileBody);
            // 解决中文字符？的问题
            ContentType contentType = ContentType.create("text/plain", Charset.forName("UTF-8"));

        Map<String,String> messMap = JSON.parseObject(data, Map.class);
        for (Map.Entry<String, String> entry : messMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            builder.addPart(key, new StringBody(value, contentType));
        }
//        builder.addPart("data", new StringBody(data, contentType));
            HttpEntity httpEntity = builder.build();
            httpPost.setEntity(httpEntity);
            HttpResponse response = client.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String jsonData = EntityUtils.toString(response.getEntity(),  "UTF-8");

                return JSON.parseObject(jsonData,Map.class);
            } else {
                HashMap<String, String> map = new HashMap<>();
                map.put("code","0");
                map.put("mess","失败");
                return map;
            }
        }

    }






